//----------------------------------------------------------------------------------------
// @Project Includes
#include "includes.h"

//----------------------------------------------------------------------------------------
// @Local Macro Define in the module

//----------------------------------------------------------------------------------------
// @Local Type defines in the module

//----------------------------------------------------------------------------------------
// @Global Variables define in the module
stc_can_t g_stccan = {0};

//----------------------------------------------------------------------------------------
// @Prototypes of functions in the module
static void drv_can_filterInit(void);
static void drv_can_errorIntInit(void);

//========================================================================================
/**
 * @brief  This function handles CAN1 SCE Handler.
 */
void CAN_SCE_IRQHandler(void)
{
//		static uint16_t u16errorflag = 0;
	
    /*Error Warning Interrupt*/
    if(SET==CAN_GetIntStatus(CAN, CAN_INT_EWG))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_EWG);
//			 SetBit(u16errorflag,0);
    }
    /*Error Passive Interrupt*/
    else if(SET==CAN_GetIntStatus(CAN, CAN_ESTS_EPVFL))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_EPV);
//			 SetBit(u16errorflag,1);
    }
    /* Bus-Off Interrupt */
    else if(SET==CAN_GetIntStatus(CAN, CAN_INT_BOF))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_BOF);
//			 SetBit(u16errorflag,2);			
    }
    /*Last Error Code Interrupt*/
    else  if(SET==CAN_GetIntStatus(CAN, CAN_ESTS_LEC))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_LEC);
//			 SetBit(u16errorflag,3);			
    }
    /*Error Code Interrupt Enable*/
    else  if(SET==CAN_GetIntStatus(CAN, CAN_INT_ERR))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_ERR);
//			 SetBit(u16errorflag,4);			
    }
    /*FIFO Message Pending Interrupt*/
    else  if(SET==CAN_GetIntStatus(CAN, CAN_INT_FMP0))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_FMP0);
//			 SetBit(u16errorflag,5);			
    }
    /*FIFO Full Interrupt Enable*/
    else  if(SET==CAN_GetIntStatus(CAN, CAN_INT_FF0))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_FF0);
//			 SetBit(u16errorflag,6);			
    }
    /*FIFO Overrun Interrupt Enable*/
    else  if(SET==CAN_GetIntStatus(CAN, CAN_INT_FOV0))
    {
       CAN_ClearINTPendingBit(CAN, CAN_INT_FOV0);
//			 SetBit(u16errorflag,7);			
    }
//		g_stcVar.u16canError = u16errorflag;
}

/**
 * @brief  This function handles CAN RX0 Handler.
 */
void CAN_RX0_IRQHandler(void)
{
    if (g_stccan.vu8canRxMQPushLen < CAN_MAX_RX_SIZE)/*保护，防止溢出*/
    {
        CAN_ReceiveMessage(CAN, CAN_FIFO0, &g_stccan.canRxMessage[g_stccan.vu8canRxMQPushLen++]);
    }
    if (g_stccan.vu8canRxMQPushLen >= CAN_MAX_RX_SIZE)
    {
        g_stccan.vu8canRxMQPushLen = 0;
    }
//		g_stcVar.u16canError = 0;
}

/*
 * @Functions:   static void drv_can_filterInit(void)
 * @Description: Configures CAN Filer.
 * @Parameters:  NONE
 * @Return:      NONE
 */ 
static void drv_can_filterInit(void)
{
    CAN_FilterInitType CAN_FilterInitStructure;
    /* CAN filter init */
    CAN_FilterInitStructure.Filter_Num            = CAN_FILTERNUM0;
    CAN_FilterInitStructure.Filter_Mode           = CAN_Filter_IdMaskMode;
    CAN_FilterInitStructure.Filter_Scale          = CAN_Filter_32bitScale;
    CAN_FilterInitStructure.Filter_HighId         = CAN_FILTER_EXTID_H(0x400);
    CAN_FilterInitStructure.Filter_LowId          = CAN_FILTER_EXTID_L(0x400);
    CAN_FilterInitStructure.FilterMask_HighId     = CAN_EXT_ID_H_MASK_DONT_CARE;
    CAN_FilterInitStructure.FilterMask_LowId      = CAN_EXT_ID_L_MASK_DONT_CARE;
    CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;
    CAN_FilterInitStructure.Filter_Act            = ENABLE;
    CAN_InitFilter(&CAN_FilterInitStructure);

}

/*
 * @Functions:   static void drv_can_errorIntInit(void)
 * @Description: Configures CAN error int.
 * @Parameters:  NONE
 * @Return:      NONE
 */ 
static void drv_can_errorIntInit(void)
{
    /*Error Warning Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_EWG,ENABLE);
    /*Error Passive Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_EPV,ENABLE);
    /*Bus-Off Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_BOF,ENABLE);
    /*Last Error Code Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_LEC,ENABLE);
    /*Error Code Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_ERR,ENABLE);
    /*FIFO Message Pending Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_FMP0,ENABLE);
    /*FIFO Full Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_FF0,ENABLE);
    /*FIFO Overrun Interrupt Enable*/
    CAN_INTConfig(CAN,CAN_INT_FOV0,ENABLE);
	
}

/*
 * @Functions:   uint8_t drv_can_txMessage(CAN_Module* CANx,CanTxMessage* TxMessage)
 * @Description: TxMessage CAN_TxMessage.
 * @Parameters:  NONE
 * @Return:      NONE
 */
uint8_t drv_can_txMessage(CAN_Module* CANx,CanTxMessage* TxMessage)
{
    return CAN_TransmitMessage(CANx, TxMessage);
}

/*
 * @Functions:   void drv_can_init(void)
 * @Description: CAN总线初始化
 * @Parameters:  NONE
 * @Return:      NONE
 */
void drv_can_init(void)
{
    NVIC_InitType NVIC_InitStructure;
    GPIO_InitType GPIO_InitStructure;
    CAN_InitType CAN_InitStructure;	
	
    /* Configures CAN1 GPIOs****************************/
    GPIO_InitStruct(&GPIO_InitStructure);
    /* Configures CAN IOs */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO | CAN_GPIO_CLK, ENABLE);
    /* Configure CAN RX PB8 */
    GPIO_InitStructure.Pin       = CAN_RX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF1_CAN;
    GPIO_InitPeripheral(CAN_RX_PORT, &GPIO_InitStructure);
    /* Configure CAN TX PB9 */
    GPIO_InitStructure.Pin        = CAN_TX_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitPeripheral(CAN_TX_PORT, &GPIO_InitStructure);

    /* Remap CAN1 GPIOs */
    //GPIO_ConfigPinRemap(GPIO_RMP1_CAN1, ENABLE);	
	
    /* Configures CAN .****************************/
    /* Configure CAN  */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN , ENABLE);
    /* CAN1 and CAN register init */
    CAN_DeInit(CAN);
    /* Struct init*/
    CAN_InitStruct(&CAN_InitStructure);
    /* CAN1  cell init */
    CAN_InitStructure.TTCM          = DISABLE;
    CAN_InitStructure.ABOM          = ENABLE;
    CAN_InitStructure.AWKUM         = DISABLE;
    CAN_InitStructure.NART          = DISABLE;
    CAN_InitStructure.RFLM          = DISABLE;
    CAN_InitStructure.TXFP          = ENABLE;
    CAN_InitStructure.OperatingMode = CAN_Normal_Mode;
    CAN_InitStructure.RSJW          = CAN_BIT_RSJW;
    CAN_InitStructure.TBS1          = CAN_BIT_BS1;
    CAN_InitStructure.TBS2          = CAN_BIT_BS2;
    CAN_InitStructure.BaudRatePrescaler = CAN_BAUDRATEPRESCALER;
    /*Initializes the CAN1 */
    CAN_Init(CAN, &CAN_InitStructure);
		/* CAN filter init */
    drv_can_filterInit();	
		drv_can_errorIntInit();
		
    /* Configures the NVIC for CAN.****************************/
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_InitStructure.NVIC_IRQChannel                   = CAN_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/*抢断*/
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 2;/*响应*/
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;		
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel                   = CAN_SCE_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 4;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}

///*
// * @Functions:   void drv_can_sleep(void)
// * @Description: CAN休眠
// * @Parameters:  NONE
// * @Return:      NON
// */
//void drv_can_sleep(void)
//{
//		drv_gpio_outputInit (CAN_TX_PORT, CAN_TX_PIN,GPIO_Mode_Input); 
//		drv_gpio_outputInit (CAN_RX_PORT, CAN_RX_PIN,GPIO_Mode_Input); 
//}

///*
// * @Functions:   void drv_can_wakeup(void)
// * @Description: CAN唤醒
// * @Parameters:  NONE
// * @Return:      NON
// */
//void drv_can_wakeup(void)
//{
//    /*CAN唤醒*/
//    drv_can_init();
//}

///*
// * @Functions:   void drv_can_10msInt(void)
// * @Description: CAN定时中断调用
// * @Parameters:  NONE
// * @Return:      NONE
// */
//void drv_can_10msInt(void)
//{
//    g_stccan.u16canTx100msTimeCnt++;
//    g_stccan.u16canTx500msTimeCnt++;
//    g_stccan.u16canTx1000msTimeCnt++;
//	
//}

// =======================================================================================
// End of file.
// =======================================================================================
